using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace LabyrinthProject
{

    enum WalllType
    { 
        normalWallSegment,
        startWallSegment,
        exitWallSegment
    }

    class WallElement
    {
        private BoundingBox boundingBox;
        private WalllType wallType;

        private Quad beginQuad;
        private Quad endQuad;
        private Quad leftQuad;
        private Quad rightQuad;
        private Quad topQuad;

        private float wallLength;
        private float wallHeight;
        private float wallWide;
        private float resize;

        private Vector2 direction;
        private Vector2 begin;
        private Vector2 end;

        public WalllType WallType
        {
            get 
            { 
                return wallType; 
            }
            set 
            { 
                wallType = value; 
            }
        }

        public BoundingBox BoundingBox
        {
            get
            {
                return boundingBox;
            }
            set
            {
                boundingBox = value;
            }
        }
        
        public Quad BeginQuad
        {
            get
            {
                return beginQuad;
            }
            set
            {
                beginQuad = value;
            }
        }
        public Quad EndQuad
        {
            get
            {
                return endQuad;
            }
            set
            {
                endQuad = value;
            }
        }
        public Quad LeftQuad
        {
            get
            {
                return leftQuad;
            }
            set
            {
                leftQuad = value;
            }
        }
        public Quad RightQuad
        {
            get
            {
                return rightQuad;
            }
            set
            {
                rightQuad = value;
            }
        }
        public Quad TopQuad
        {
            get
            {
                return topQuad;
            }
            set
            {
                topQuad = value;
            }
        }

        public float Resize
        {
            get
            {
                return resize;
            }
            set
            {
                resize = value;
            }
        }

        public float WallLength
        {
            get { return wallLength; }
        }
        public float WallHeight
        {
            get
            {
                return wallHeight;
            }
            set
            {
                wallHeight = value;
            }
        }
        public float WallWide
        {
            get
            {
                return wallWide;
            }
            set
            {
                wallWide = value;
            }
        }

        public Vector2 Direction
        {
            get { return direction; }
            set { direction = value; }
        }
        public Vector2 Begin
        {
            get
            {
                return begin;
            }
            set
            {
                begin = value;
            }
        }
        public Vector2 End
        {
            get
            {
                return end;
            }
            set
            {
                end = value;
            }
        }

        public WallElement(Vector2 beginigOfWall, Vector2 endOfWall, WalllType wallType)
        {

            this.wallType = wallType; ;
            initializyWallElement(beginigOfWall, endOfWall);


        }

        public WallElement( Vector2 beginigOfWall, Vector2 endOfWall )
        {
            this.wallType = WalllType.normalWallSegment;
            initializyWallElement(beginigOfWall, endOfWall);
        }

        private void initializyWallElement(Vector2 beginigOfWall, Vector2 endOfWall)
        {
            this.begin = beginigOfWall;
            this.end = endOfWall;
            
            this.wallWide = 0.2f;
            this.wallHeight = 1f;
            this.wallLength = (endOfWall - beginigOfWall).Length();
            this.direction = end - begin;
            this.direction.Normalize();
            this.resize = 1000;

            createQuads();

            if (System.Math.Abs(direction.X) == 1)
            {
                boundingBox = new BoundingBox(beginQuad.LowerLeft, endQuad.UpperLeft);
            }
            else
            {
                boundingBox = new BoundingBox(beginQuad.LowerRight, endQuad.UpperRight);
            }
        }

        private void createQuads()
        {
            float wallLength = (float)( end - begin ).Length();
            float overlap = .999f;

            Vector2 direction2D = end - begin;
            Vector3 direction3D = new Vector3( direction2D.X, 0, direction2D.Y );
            direction3D.Normalize();

            Vector2 center2D = begin + ( end - begin ) / 2.0f;
            Vector3 center3D = new Vector3( center2D.X, 0f, center2D.Y );

            Vector3 normal = Vector3.Cross( Vector3.Up, direction3D );
            normal.Normalize();

            if ( direction3D == Vector3.Right )
            {
                overlap = .9998f;
            }


            leftQuad = new Quad( ( center3D - normal * wallWide / 2f ) * resize, -normal, Vector3.Up, ( wallLength + wallWide ) * resize, wallHeight * resize );

            rightQuad = new Quad( ( center3D + normal * wallWide / 2f ) * resize, normal, Vector3.Up, ( wallLength + wallWide ) * resize, wallHeight * resize );

            beginQuad = new Quad( ( new Vector3( begin.X, 0, begin.Y ) - 0.98f * direction3D * wallWide / 2f ) * resize, -direction3D, Vector3.Up, wallWide * resize, wallHeight * resize );

            endQuad = new Quad( ( new Vector3( end.X, 0, end.Y ) + 0.98f * direction3D * wallWide / 2f ) * resize, direction3D, Vector3.Up, wallWide * resize, wallHeight * resize );

            topQuad = new Quad( ( new Vector3( begin.X, 0, begin.Y ) - direction3D * wallWide / 2f + wallHeight * Vector3.Up * overlap ) * resize, Vector3.Up, direction3D, wallWide * resize, ( wallLength + wallWide ) * resize );
        }
    }
}
